package config

import (
	"context"
	"fmt"

	"github.com/glennliao/apijson-go/model"
	"github.com/gogf/gf/v2/container/gvar"
	"github.com/gogf/gf/v2/frame/g"
)

const (
	C参数类型整型  = "int"
	C参数类型字符串 = "string"
	C来源响应数据  = "res" // 只从响应的数据字段中取, 不从用户传递的数据取
)

type C参数项 struct {
	L类型   string
	M名称   string
	M描述   string
	M默认值  any
	L来源   string // 指定参数从何处取值
	X校验规则 string // 参数校验规则
}

type H函数定义 struct {
	M描述 string // 函数描述
	// 参数可直接读取函数参数传递过来的， ''括起来
	C参数列表 []C参数项 // 参数列表 // TODO 限制参数来源，强制用户传递的无法覆盖内部的，减免权限的重复判断，参数校验限制（最大值，最小值，默认值，自定义校验。使用gvaild）

	P批量处理 bool // 是否为批量处理, 例如在获取列表后一次性将id传入, 然后按照传入的参数数组返回结果数组
	C处理函数 func(ctx context.Context, 参数 model.FuncParam) (结果 any, 错误 error)
}

type H函数集合 struct {
	H函数映射 map[string]*H函数定义
}

func (集合 *H函数集合) B绑定函数(名称 string, 函数 H函数定义) {
	if _, 已存在 := 集合.H函数映射[名称]; 已存在 {
		panic(fmt.Errorf("函数 %s 已存在", 名称))
	}
	集合.H函数映射[名称] = &函数
}

func (集合 *H函数集合) T调用函数(ctx context.Context, 名称 string, 参数 g.Map) (any, error) {
	参数映射 := map[string]model.Var{}
	for 键, 值 := range 参数 {
		参数映射[键] = gvar.New(值)
	}

	return 集合.H函数映射[名称].C处理函数(ctx, 参数映射)
}

// 函数集合 可能提供的功能
// 1. 增加响应字段 -> 该字段需要与系统中别的数据结合处理,如果只是静态处理(去空格,与常量拼接等可直接前端处理即可) 目前会不受_access_ext 中field_get控制, 需处理. 响应字段修改(脱敏、加密、字典转换) 不提供前端控制, 由_access_ext处理
// 2. 通过func节点获取一些系统信息
// 3. actions 中 自定义校验参数、自定义校验权限, 请求体修改(批量字段替换处理?)
// 4. 其他需要自定义的地方 (在action中可看成是hook的替代)

// 函数集合 可用于 field_get 使用, 用于修改请求、响应
